package com.mzj.saas.rent;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.haixiaoke.saas.repository.core.AjaxResult;
import com.haixiaoke.saas.repository.core.BaseController;
import com.haixiaoke.saas.repository.exception.BizException;
import com.haixiaoke.saas.repository.pojo.ContractParameter;
import com.haixiaoke.saas.repository.pojo.Order;
import com.haixiaoke.saas.repository.pojo.OrderContract;
import com.haixiaoke.saas.repository.service.IContractTemplateService;
import com.haixiaoke.saas.repository.service.IOrderAmountItemService;
import com.haixiaoke.saas.repository.service.IOrderContractService;
import com.haixiaoke.saas.repository.service.IOrderService;
import com.haixiaoke.saas.repository.util.PlaceholderUtil;
import com.mzj.saas.annotation.CheckAuth;
import com.mzj.saas.annotation.RepeatSubmit;
import com.mzj.saas.commons.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单合同Controller
 *
 * @author zhiping
 * @date 2023-4-20
 */
@RestController
@RequestMapping("/order/contract")
public class OrderContractController extends BaseController {


    @Autowired
    private IContractTemplateService contractTemplateService;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private IOrderContractService orderContractService;

    @Autowired
    private IOrderAmountItemService orderAmountItemService;

    /**
     * 根据订单生成合同内容
     *
     * @param orderId
     * @return
     */
    @CheckAuth
    @GetMapping(value = "/generate/{orderId}")
    public AjaxResult generate(@PathVariable("orderId") String orderId) {

        Order order = orderService.selectOrderById(orderId);
        // 校验订单状态
        if (Order.ORDER_STATE_CANCELED.equals(order.getOrderState()) || Order.ORDER_STATE_REFUND.equals(order.getOrderState())
                || Order.ORDER_STATE_UN_PAYMENT.equals(order.getOrderState())) {
            throw new BizException(50001, "订单状态异常");
        }

        // TODO 校验当前时间是否运行入住
        // getCheckInTime(order);

        // 已经生成过合同
        List<OrderContract> orderContracts = orderContractService.selectOrderContractByOrderIdAndStatus(orderId, OrderContract.CONTRACT_STATUS_NO);
        if (orderContracts.size() > 1) {
            return AjaxResult.error("合同数据异常");
        }
        OrderContract orderContract = null;
        if (CollectionUtil.isNotEmpty(orderContracts) ) {
            orderContract = orderContracts.get(0);
        }
        if (ObjectUtil.isNotEmpty(orderContract)) {
            HashMap<String, Object> result = new HashMap<>();
            result.put("content", orderContract.getContent());
            result.put("contractId", orderContract.getContractId());
            return AjaxResult.success(result);
        }
        Long orgId = order.getOrgId();
        String template = contractTemplateService.selectContractTemplateByOrgId(orgId);

        if (StrUtil.isBlank(template)) {
            // 没有自定义模板, 则启用默认模板
            template = contractTemplateService.selectContractTemplateByOrgId(0L);
        }
        // 模板填充内容
        ContractParameter contractParameter = buildContractParameter(orderId);
        Map<String, Object> map = BeanUtil.beanToMap(contractParameter);
        String content = PlaceholderUtil.format(template, map);

        // 保存合同
        OrderContract newContract = OrderContract.builder().orderId(orderId).orgId(orgId)
                .userId(order.getReservationId()).content(content)
                .checkInTime(order.getCheckInTime()).checkOutTime(order.getCheckOutTime())
                .contentTemplate(template).build();
        orderContractService.insertOrderContract(newContract);

        HashMap<String, Object> result = new HashMap<>();
        result.put("content", content);
        result.put("contractId", newContract.getContractId());

        return AjaxResult.success(result);
    }

    /**
     * 查询最新的合同
     * @param orderId
     * @return
     */
    @GetMapping(value = "/contractContent/{orderId}")
    public AjaxResult contractContent(@PathVariable("orderId") String orderId){
        List<OrderContract> orderContracts = orderContractService.selectOrderContractByOrderIdAndStatus(orderId,OrderContract.CONTRACT_STATUS_YES);

        if (CollectionUtil.isNotEmpty(orderContracts)) {
            // 筛选最新时间
            List<OrderContract> filteredList = orderContracts.stream()
                    .sorted(Comparator.comparing(OrderContract::getSignTime).reversed())
                    .collect(Collectors.toList());
            HashMap<String, Object> result = new HashMap<>();
            result.put("content", filteredList.get(0).getContent());
            result.put("contractId", filteredList.get(0).getContractId());
            result.put("signImg",filteredList.get(0).getSignImg());
            return AjaxResult.success(result);
        }
        return error("该订单还没签订合同");
    }


    /**
     * 签订合同
     *
     * @param orderContract
     * @return
     */
    @CheckAuth
    @PostMapping(value = "/sign")
    @RepeatSubmit
    public AjaxResult sign(@RequestBody OrderContract orderContract) {

        Order order = orderService.selectOrderById(orderContract.getOrderId());
        // 校验订单状态
        if (Order.ORDER_STATE_CANCELED.equals(order.getOrderState()) || Order.ORDER_STATE_REFUND.equals(order.getOrderState())
                || Order.ORDER_STATE_UN_PAYMENT.equals(order.getOrderState())) {
            throw new BizException(50001, "订单状态异常");
        }

        int i = orderContractService.updateOrderContract(orderContract);
        return AjaxResult.success(i > 0 ? "合同签订完成" : "合同签订失败");
    }

    /**
     * 构造合同模板填充所需的内容
     *
     * @param orderId
     * @return
     */
    @CheckAuth
    private ContractParameter buildContractParameter(String orderId) {
        Order order = orderService.selectOrderById(orderId);
        // 全地址
        String fullAddress = order.getFullAddress();
        // 甲方
        String houseOwnerName = order.getHouseOwnerName();
        String houseOwnerPhone = order.getHouseOwnerPhone();

        // 乙方
        String reservationName = order.getReservationName();
        String reservationPhone = order.getReservationPhone();
        String idCardNumber = order.getReservationCardNumber();

        // 租赁期限
        Date checkInTime = order.getCheckInTime();
        Date checkOutTime = order.getCheckOutTime();
        String timeRange = DateUtil.format(checkInTime, "yyyy-MM-dd") + " ~ " + DateUtil.format(checkOutTime, "yyyy-MM-dd");

        // 租金
        String priceAmounts = Convert.toStr(order.getPriceAmounts());

        // 押金
        // biz_order_amount_item  goods_type(1:房屋价格；2:保洁费；3:押金；)
        Double deposit = orderAmountItemService.selectDepositByOrderId(orderId);

        // 面积
        String area = Convert.toStr(order.getArea());

        // 房型
        String houseType = order.getHouseType();

        // 合同签订日期
        String day = DateUtil.today();

        return ContractParameter.builder().address(fullAddress)
                .timeRange(timeRange).partyAName(houseOwnerName)
                .partyAContact(houseOwnerPhone)
                .partyBName(reservationName)
                .partyBContact(reservationPhone)
                .partyBIdNumber(idCardNumber)
                .deposit(Convert.toStr(deposit))
                .area(area).houseType(houseType)
                .day(day)
                .rentAmount(priceAmounts)
                .build();
    }


    /**
     * 校验当前时间是否允许入住
     */
    private boolean getCheckInTime(Order order) {
        Date checkInTime = order.getCheckInTime();
        if (checkInTime.getTime() > new Date().getTime()) {
            Integer code = Convert.toInt(StatusCode.ERROR_CODE_10001.getErrorCode());
            throw new BizException(code, "未到预定时间,无法入住!");
        }
        return true;
    }
}
